// 版权所有2016 Go作者。版权所有。
// 此源代码的使用受BSD样式
// 许可证的约束，该许可证可以在许可证文件中找到。

// 我们以前在达尔文使用此代码，但根据问题#19314 
// 如果进程停止，即使使用WEXITED，waitid也会返回。

// go:build linux 
// +build linux 

package os

import (
	"runtime"
	"syscall"
	"unsafe"
)

const _P_PID = 1

// blockUntilWaitable尝试阻止，直到调用p。Wait将立即成功，并报告是否已成功。
// 它实际上不调用p.Wait。
func (p *Process) blockUntilWaitable() (bool, error) {
	// waitid系统调用需要一个指向siginfo\u t的指针，
	// 在所有Linux系统上都是128字节。
	// 在darwin/amd64上，它需要104字节。
	// 我们不关心它返回的值。
	var siginfo [16]uint64
	psig := &siginfo[0]
	var e syscall.Errno
	for {
		_, _, e = syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
		if e != syscall.EINTR {
			break
		}
	}
	runtime.KeepAlive(p)
	if e != 0 {
		// waitid从Linux 2.6.9开始提供，但据报道，在Windows上的Ubuntu中不提供。
		// 见第16610期。
		if e == syscall.ENOSYS {
			return false, nil
		}
		return false, NewSyscallError("waitid", e)
	}
	return true, nil
}
